#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
日志工具模块
提供应用程序日志相关的功能
"""

import os
import sys
import logging
import traceback
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Optional

from config.constants import APP_NAME, LOG_LEVEL, LOG_FORMAT, LOG_FILE


def setup_logger(name: Optional[str] = None, level: Optional[str] = None) -> logging.Logger:
    """设置日志记录器
    
    Args:
        name: 日志记录器名称
        level: 日志级别
        
    Returns:
        配置好的日志记录器
    """
    if name is None:
        name = APP_NAME
        
    if level is None:
        level = LOG_LEVEL
        
    # 获取日志级别
    log_level = getattr(logging, level.upper(), logging.INFO)
    
    # 创建日志记录器
    logger = logging.getLogger(name)
    logger.setLevel(log_level)
    
    # 确保不重复添加处理器
    if logger.handlers:
        return logger
    
    # 确保日志目录存在
    log_path = Path(LOG_FILE).parent
    os.makedirs(log_path, exist_ok=True)
    
    # 创建文件处理器 (带日志滚动)
    file_handler = RotatingFileHandler(
        LOG_FILE, 
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5,
        encoding='utf-8'
    )
    file_handler.setLevel(log_level)
    
    # 创建控制台处理器
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(log_level)
    
    # 设置格式器
    formatter = logging.Formatter(LOG_FORMAT)
    file_handler.setFormatter(formatter)
    console_handler.setFormatter(formatter)
    
    # 添加处理器
    logger.addHandler(file_handler)
    logger.addHandler(console_handler)
    
    return logger


def log_exception(logger: logging.Logger, e: Exception, message: Optional[str] = None) -> None:
    """记录异常信息
    
    Args:
        logger: 日志记录器
        e: 异常
        message: 额外的错误消息
    """
    exc_info = sys.exc_info()
    stack_trace = ''.join(traceback.format_exception(*exc_info))
    
    if message:
        error_message = f"{message}: {str(e)}\n{stack_trace}"
    else:
        error_message = f"异常: {str(e)}\n{stack_trace}"
    
    logger.error(error_message)


def get_logger(name: str) -> logging.Logger:
    """获取指定名称的日志记录器
    
    Args:
        name: 日志记录器名称
        
    Returns:
        日志记录器
    """
    return setup_logger(name)
